#include <unistd.h>
#include <string.h>

#include "mm_task.h"
#include "log.h"
#include "msg.h"
#include "mail.h"

#define USLEEP_TIME_MM_TASK 100000

int mm_ops(struct msg *msg)
{
	log_info("begin mm_ops.");

	return 0;
}

void *mm_loop(void *data)
{
	log_info("begin mm_loop.");	

	unsigned int send_mail_count = 0;

	while (1) {
		unsigned long mm_limit = core_conf.mm_limit;
		char warning_msg[4096] = "You Need To Check Your Program Now !\n";
		char tmp_msg[128] = {'\0'};

		sprintf(tmp_msg, "Memory Limitation is %lu bytes.\nBut:\n\n", mm_limit);
		strcat(warning_msg, tmp_msg);

		int need_send_mail = 0;

		struct task_manager *task_manager = core_conf.task_manager;
		int ut = core_conf.usleep_time >= USLEEP_TIME_MM_TASK ? core_conf.usleep_time : USLEEP_TIME_MM_TASK;
	
		if (task_manager == NULL) {
			log_error("task_manager is NULL.");
			usleep(ut);
			continue;
		}

		pthread_mutex_lock(&(task_manager->lock));
		if (task_manager->count == 0) {
			pthread_mutex_unlock(&(task_manager->lock));
			usleep(ut);
			continue;
		}
		struct task *task = task_manager->task_head;

		for (; task != NULL; task = task->next) {
			/* we are just care about user mode task. */
			if (task->is_default == 0) {
				if (task->mm->total >= mm_limit) {
					need_send_mail = 1;
					log_error("Task: %s used too much memory!", task->task_name);
					/* We can do something here more than just log an error message. */
					log_print("===============WARNING===============");
					log_print("==Task %s used too much memory==", task->task_name);
					log_print("=====================================");

					char tmp[128] = {'\0'};
					sprintf(tmp, "Task \"%s\" used %lu bytes.\n", task->task_name, task->mm->total);

					strcat(warning_msg, tmp);
				}
			}
		}

		if (core_conf.use_mail == 1 && send_mail_count % 1000 == 0 && need_send_mail == 1) {
			need_send_mail = 0;
			send_mail_count++;
			send_mail(core_conf.to, "MEMORY WARNING", warning_msg);
		}

		pthread_mutex_unlock(&(task_manager->lock));
		usleep(ut);
	}
}
